<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<meta name="generator" content="hevea 2.18">
<link rel="stylesheet" type="text/css" href="manual.css">
<title>Chapter&#XA0;34&#XA0;&#XA0;The bigarray library</title>
</head>
<body>
<a href="libdynlink.html"><img src="previous_motif.gif" alt="Previous"></a>
<a href="index.html"><img src="contents_motif.gif" alt="Up"></a>
<a href="manual049.html"><img src="next_motif.gif" alt="Next"></a>
<hr>
<h1 class="chapter" id="sec560">Chapter&#XA0;34&#XA0;&#XA0;The bigarray library</h1>
<ul>
<li><a href="libbigarray.html#sec561">34.1&#XA0;&#XA0;Module <span class="c003">Bigarray</span>: large, multi-dimensional, numerical arrays</a>
</li><li><a href="libbigarray.html#sec562">34.2&#XA0;&#XA0;Big arrays in the OCaml-C interface</a>
</li></ul>
<p>The <span class="c003">bigarray</span> library implements large, multi-dimensional, numerical
arrays. These arrays are called &#X201C;big arrays&#X201D; to distinguish them
from the standard OCaml arrays described in
<a href="libref/Array.html">Module <span class="c003">Array</span></a>.
The main differences between &#X201C;big arrays&#X201D; and standard OCaml arrays
are as follows:
</p><ul class="itemize"><li class="li-itemize">
Big arrays are not limited in size, unlike OCaml arrays
(<span class="c003">float array</span> are limited to 2097151 elements on a 32-bit platform,
other <span class="c003">array</span> types to 4194303 elements).
</li><li class="li-itemize">Big arrays are multi-dimensional. Any number of dimensions
between 1 and 16 is supported. In contrast, OCaml arrays are
mono-dimensional and require encoding multi-dimensional arrays as
arrays of arrays.
</li><li class="li-itemize">Big arrays can only contain integers and floating-point
numbers, while OCaml arrays can contain arbitrary OCaml data types.
However, big arrays provide more space-efficient storage of integer
and floating-point elements, in particular because they support
&#X201C;small&#X201D; types such as single-precision floats and 8 and 16-bit
integers, in addition to the standard OCaml types of double-precision
floats and 32 and 64-bit integers.
</li><li class="li-itemize">The memory layout of big arrays is entirely compatible with that
of arrays in C and Fortran, allowing large arrays to be passed back
and forth between OCaml code and C / Fortran code with no data copying
at all.
</li><li class="li-itemize">Big arrays support interesting high-level operations that normal
arrays do not provide efficiently, such as extracting sub-arrays and
&#X201C;slicing&#X201D; a multi-dimensional array along certain dimensions, all
without any copying.
</li></ul><p>
Programs that use the <span class="c003">bigarray</span> library must be linked as follows:
</p><pre>
        ocamlc <span class="c009">other options</span> bigarray.cma <span class="c009">other files</span>
        ocamlopt <span class="c009">other options</span> bigarray.cmxa <span class="c009">other files</span>
</pre><p>
For interactive use of the <span class="c003">bigarray</span> library, do:
</p><pre>
        ocamlmktop -o mytop bigarray.cma
        ./mytop
</pre><p>
or (if dynamic linking of C libraries is supported on your platform),
start <span class="c003">ocaml</span> and type <span class="c003">#load "bigarray.cma";;</span>.</p>
<h2 class="section" id="sec561">34.1&#XA0;&#XA0;Module <span class="c003">Bigarray</span>: large, multi-dimensional, numerical arrays</h2>
<ul class="ftoc2"><li class="li-links">
<a href="libref/Bigarray.html">Module <span class="c003">Bigarray</span></a>
</li></ul>
<h2 class="section" id="sec562">34.2&#XA0;&#XA0;Big arrays in the OCaml-C interface</h2>
<p>C stub code that interface C or Fortran code with OCaml code, as
described in chapter&#XA0;<a href="intfc.html#c%3Aintf-c">20</a>, can exploit big arrays as
follows.</p>
<h3 class="subsection" id="sec563">34.2.1&#XA0;&#XA0;Include file</h3>
<p>The include file <span class="c003">&lt;caml/bigarray.h&gt;</span> must be included in the C stub
file. It declares the functions, constants and macros discussed
below.</p>
<h3 class="subsection" id="sec564">34.2.2&#XA0;&#XA0;Accessing an OCaml bigarray from C or Fortran</h3>
<p>If <span class="c009">v</span> is a OCaml <span class="c003">value</span> representing a big array, the expression
<span class="c003">Caml_ba_data_val(</span><span class="c009">v</span><span class="c003">)</span> returns a pointer to the data part of the array.
This pointer is of type <span class="c003">void *</span> and can be cast to the appropriate C
type for the array (e.g. <span class="c003">double []</span>, <span class="c003">char [][10]</span>, etc).</p><p>Various characteristics of the OCaml big array can be consulted from C
as follows:
</p><div class="center"><table class="c000 cellpadding1" border=1><tr><td class="c014"><span class="c013">C expression</span></td><td class="c014"><span class="c013">Returns</span> </td></tr>
<tr><td class="c016">
<span class="c003">Caml_ba_array_val(</span><span class="c009">v</span><span class="c003">)-&gt;num_dims</span></td><td class="c016">number of dimensions </td></tr>
<tr><td class="c016"><span class="c003">Caml_ba_array_val(</span><span class="c009">v</span><span class="c003">)-&gt;dim[</span><span class="c009">i</span><span class="c003">]</span></td><td class="c016"><span class="c009">i</span>-th dimension </td></tr>
<tr><td class="c016"><span class="c003">Caml_ba_array_val(</span><span class="c009">v</span><span class="c003">)-&gt;flags &amp; BIGARRAY_KIND_MASK</span></td><td class="c016">kind of array elements </td></tr>
</table></div><p>
The kind of array elements is one of the following constants:
</p><div class="center"><table class="c000 cellpadding1" border=1><tr><td class="c014"><span class="c013">Constant</span></td><td class="c014"><span class="c013">Element kind</span> </td></tr>
<tr><td class="c016">
<span class="c003">CAML_BA_FLOAT32</span></td><td class="c016">32-bit single-precision floats </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_FLOAT64</span></td><td class="c016">64-bit double-precision floats </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_SINT8</span></td><td class="c016">8-bit signed integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_UINT8</span></td><td class="c016">8-bit unsigned integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_SINT16</span></td><td class="c016">16-bit signed integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_UINT16</span></td><td class="c016">16-bit unsigned integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_INT32</span></td><td class="c016">32-bit signed integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_INT64</span></td><td class="c016">64-bit signed integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_CAML_INT</span></td><td class="c016">31- or 63-bit signed integers </td></tr>
<tr><td class="c016"><span class="c003">CAML_BA_NATIVE_INT</span></td><td class="c016">32- or 64-bit (platform-native) integers </td></tr>
</table></div><p>
The following example shows the passing of a two-dimensional big array
to a C function and a Fortran function.
</p><pre>    extern void my_c_function(double * data, int dimx, int dimy);
    extern void my_fortran_function_(double * data, int * dimx, int * dimy);

    value caml_stub(value bigarray)
    {
      int dimx = Caml_ba_array_val(bigarray)-&gt;dim[0];
      int dimy = Caml_ba_array_val(bigarray)-&gt;dim[1];
      /* C passes scalar parameters by value */
      my_c_function(Caml_ba_data_val(bigarray), dimx, dimy);
      /* Fortran passes all parameters by reference */
      my_fortran_function_(Caml_ba_data_val(bigarray), &amp;dimx, &amp;dimy);
      return Val_unit;
    }
</pre>
<h3 class="subsection" id="sec565">34.2.3&#XA0;&#XA0;Wrapping a C or Fortran array as an OCaml big array</h3>
<p>A pointer <span class="c009">p</span> to an already-allocated C or Fortran array can be
wrapped and returned to OCaml as a big array using the <span class="c003">caml_ba_alloc</span>
or <span class="c003">caml_ba_alloc_dims</span> functions.
</p><ul class="itemize"><li class="li-itemize">
<span class="c003">caml_ba_alloc(</span><span class="c009">kind</span> <span class="c003">|</span> <span class="c009">layout</span>, <span class="c009">numdims</span>, <span class="c009">p</span>, <span class="c009">dims</span><span class="c003">)</span><p>Return an OCaml big array wrapping the data pointed to by <span class="c009">p</span>.
<span class="c009">kind</span> is the kind of array elements (one of the <span class="c003">CAML_BA_</span>
kind constants above). <span class="c009">layout</span> is <span class="c003">CAML_BA_C_LAYOUT</span> for an
array with C layout and <span class="c003">CAML_BA_FORTRAN_LAYOUT</span> for an array with
Fortran layout. <span class="c009">numdims</span> is the number of dimensions in the
array. <span class="c009">dims</span> is an array of <span class="c009">numdims</span> long integers, giving
the sizes of the array in each dimension.</p></li><li class="li-itemize"><span class="c003">caml_ba_alloc_dims(</span><span class="c009">kind</span> <span class="c003">|</span> <span class="c009">layout</span>, <span class="c009">numdims</span>,
<span class="c009">p</span>, <span class="c003">(long) </span><span class="c009">dim</span><sub>1</sub>, <span class="c003">(long) </span><span class="c009">dim</span><sub>2</sub>, &#X2026;, <span class="c003">(long) </span><span class="c009">dim</span><sub><span class="c009">numdims</span></sub><span class="c003">)</span><p>Same as <span class="c003">caml_ba_alloc</span>, but the sizes of the array in each dimension
are listed as extra arguments in the function call, rather than being
passed as an array.
</p></li></ul><p>
The following example illustrates how statically-allocated C and
Fortran arrays can be made available to OCaml.
</p><pre>    extern long my_c_array[100][200];
    extern float my_fortran_array_[300][400];

    value caml_get_c_array(value unit)
    {
      long dims[2];
      dims[0] = 100; dims[1] = 200;
      return caml_ba_alloc(CAML_BA_NATIVE_INT | CAML_BA_C_LAYOUT,
                           2, my_c_array, dims);
    }

    value caml_get_fortran_array(value unit)
    {
      return caml_ba_alloc_dims(CAML_BA_FLOAT32 | CAML_BA_FORTRAN_LAYOUT,
                                2, my_fortran_array_, 300L, 400L);
    }
</pre>
<hr>
<a href="libdynlink.html"><img src="previous_motif.gif" alt="Previous"></a>
<a href="index.html"><img src="contents_motif.gif" alt="Up"></a>
<a href="manual049.html"><img src="next_motif.gif" alt="Next"></a>
</body>
</html>
